/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
 * 
 * 欢迎到知启蒙网站（https://www.zhiqim.com）购买正版软件，知启蒙还提供许多开源框架和软件。
 * 
 * 1、本软件产品所有源代码受《中华人民共和国著作权法》和其他有关法律、法规的保护，其所有知识产权归湖南知启蒙科技有限公司所有；
 * 2、禁止复制和修改。不得复制修改、翻译或改编本软件所有源代码，或者基于本软件产品创作衍生作品；
 * 3、禁止进行逆向工程。不得对本软件的源代码进行逆向工程、反编译或试图以其他方式发现软件的源代码；
 * 4、个别授权：如需进行商业性的销售、复制、分发，包括但不限于软件销售、预装、捆绑等，必须获得知启蒙的书面授权和许可；
 * 5、保留权利：本注释未明示授权的其他一切权利仍归知启蒙所有，任何人使用其他权利时必须获得知启蒙的书面同意。
*/
package net.redxyz.repost.service.task.repost;

import java.util.ArrayList;
import java.util.List;

import org.zhiqim.kernel.Global;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.schedule.Task;
import org.zhiqim.kernel.util.DateTimes;
import org.zhiqim.orm.ORM;
import org.zhiqim.orm.ORMServer;
import org.zhiqim.orm.ZView;
import org.zhiqim.orm.dbo.Selector;
import org.zhiqim.orm.dbo.Updater;

import net.redxyz.top.TaobaoService;
import net.redxyz.top.data.item.Item;
import net.redxyz.top.message.item.AlibabaItemOperateDownshelfResponse;
import net.redxyz.top.message.item.AlibabaItemOperateUpshelfResponse;
import net.redxyz.top.message.item.ItemSellerGetResponse4_24625;
import net.redxyz.top.repost.dbo.AssRepostSchedule;
import net.redxyz.top.repost.dbo.AssRepostScheduleTime;
import net.redxyz.top.repost.dboext.UserRepostScheduleTime;

/**
 * 每分钟检查定时上下架计划
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class RepostScheduleTask implements Task
{
    private static final Log log = LogFactory.getLog("timer.repost.log");

    public void execute()
    {
        log.info("定时上下架任务开始......");
        String time = DateTimes.getDateTimeString().substring(0, 17) + "00";

        try
        {
            // 第一步，查询需要定时上下架表
            Selector selector = new Selector();
            selector.addMaybe("userStatus", 0); // 用户状态正常
            selector.addMaybe("planStatus", 1); // 计划状态正常
            selector.addMaybe("planTime", time); // 计划时间为本分钟
            
            Selector sel = new Selector();
            sel.addMaybe("planHandleStatus", 3);//延迟调整宝贝

            List<UserRepostScheduleTime> repostList = new ArrayList<UserRepostScheduleTime>();
            int dbSize = Global.getServiceList(ORMServer.class).size();
            for (int i = 0; i < dbSize; i++)
            {
                List<UserRepostScheduleTime> list1 = ORM.get(ZView.class, i).list(UserRepostScheduleTime.class, selector);
                List<UserRepostScheduleTime> list2 = ORM.get(ZView.class, i).list(UserRepostScheduleTime.class, sel);
                repostList.addAll(list1);
                repostList.addAll(list2);
            }

            if (repostList.isEmpty())
            {
                log.info("定时上下架任务结束[本分钟没有要上下架的宝贝]");
                return;
            }

            // 第二步，对上下架进行处理
            int[] nums = new int[2];
            String datetime = DateTimes.getDateTimeString();
            for (UserRepostScheduleTime repost : repostList)
            {
                String nick = repost.getNick();
                long numIid = repost.getNumIid();
                String sessionId = repost.getSessionId();
                String planTime = repost.getPlanTime();
                Item item = doQuery(nums, nick, numIid, sessionId);
                if (item == null)
                {
                    log.info("定时上下架[" + nick + "][" + numIid + "]查询宝贝信息失败");
                    continue;
                }

                int planType = repost.getPlanType();
                switch (planType)
                {
                case 0:
                {// 仅下架
                    if (item.isOnsale())
                        doDownRepost(nums, nick, numIid, planTime, sessionId, datetime);
                    else
                    {
                        nums[0]++;
                        log.info("定时上下架[" + nick + "][" + numIid + "]该宝贝为下架状态无需操作");
                        Updater updater = new Updater();
                        updater.addMaybe("nick", nick);
                        updater.addMaybe("numIid", numIid);
                        updater.addMaybe("planTime", planTime);
                        updater.addField("planHandleStatus", 1);
                        updater.addField("planHandleTime", datetime);
                        updater.addField("planHandleDesc", null);
                        
                        ORM.table().update(AssRepostScheduleTime.class, updater);
                    }
                }
                    break;
                case 1:
                {// 仅上架
                    if (item.isOnsale())
                    {
                        nums[0]++;
                        log.info("定时上下架[" + nick + "][" + numIid + "]该宝贝为上架状态无需操作");
                        Updater updater = new Updater();
                        updater.addMaybe("nick", nick);
                        updater.addMaybe("numIid", numIid);
                        updater.addMaybe("planTime", planTime);
                        updater.addField("planHandleStatus", 1);
                        updater.addField("planHandleTime", datetime);
                        updater.addField("planHandleDesc", null);
                        
                        ORM.table().update(AssRepostScheduleTime.class, updater);
                    }
                    else
                    {
                        int num = repost.getNum() > 0 ? repost.getNum() : item.getNum();
                        doUpRepost(nums, nick, numIid, planTime, sessionId, num, datetime, false);
                    }
                }
                    break;
                default:
                {// 调整成上架

                    int num = repost.getNum() > 0 ? repost.getNum() : item.getNum();
                    if (item.isOnsale())
                        doUpdateRepost(nums, nick, numIid, planTime, sessionId, num, datetime);
                    else
                        doUpRepost(nums, nick, numIid, planTime, sessionId, num, datetime, true);
                }
                }
            }
            log.info("定时上下架结束总[" + repostList.size() + "][成功" + nums[0] + "个][失败" + nums[1] + "个]");
        }
        catch (Exception e)
        {
            log.error("定时上下架时读取要上下架的宝贝数据异常", e);
        }
    }

    /** 到淘宝查询宝贝 */
    private Item doQuery(int[] nums, String nick, long numIid, String sessionId) throws Exception
    {
        ItemSellerGetResponse4_24625 resp = TaobaoService.getItemService().getItem(nick, sessionId, numIid);
        if (resp.isTaobaoFail())
            resp = TaobaoService.getItemService().getItem(nick, sessionId, numIid);

        if (resp.isGetFail())
        {// 宝贝不存在则删除
            doDeleteItem(nick, numIid);
            nums[1]++;
            return null;
        }

        if (!resp.isSuccess())
        {
            nums[1]++;
            return null;
        }

        return resp.getItem();
    }

    /** 调整 */
    private void doUpdateRepost(int[] nums, String nick, long numIid, String planTime, String sessionId, int num, String datetime) throws Exception
    {
        //先下架
        AlibabaItemOperateDownshelfResponse resp = TaobaoService.getItemService().itemDownshelf(nick, sessionId, numIid);
        if (resp.isTaobaoFail())
            resp = TaobaoService.getItemService().itemDownshelf(nick, sessionId, numIid);

        if (!resp.isSuccess())
        {
            nums[1]++;
            if(resp.isTaobaoFail())
            {
                log.error("定时上下架[" + nick + "]调整[" + numIid + "]下架失败[" + resp.getErrorMsg() + "]，顺延到下一分钟处理");
                doHandlerNextMin(nick, numIid, planTime, datetime);
            }
            else
            {
                log.error("定时上下架[" + nick + "]调整[" + numIid + "]下架失败[" + resp.getErrorMsg() + "]");
    
                Updater updater = new Updater();
                updater.addMaybe("nick", nick);
                updater.addMaybe("numIid", numIid);
                updater.addMaybe("planTime", planTime);
                updater.addField("planHandleStatus", 2);
                updater.addField("planHandleTime", datetime);
                updater.addField("planHandleDesc", resp.getErrorMsg());
                ORM.table().update(AssRepostScheduleTime.class, updater);
            }
            
            return;
        }
        
        //后上架
        AlibabaItemOperateUpshelfResponse resp2 = TaobaoService.getItemService().itemUpshelf(nick, sessionId, numIid, num);
        if (resp2.isTaobaoFail())
            resp2 = TaobaoService.getItemService().itemUpshelf(nick, sessionId, numIid, num);

        if (!resp2.isSuccess())
        {
            nums[1]++;
            if(resp2.isTaobaoFail())
            {
                log.error("定时上下架[" + nick + "]调整[" + numIid + "]上架失败[" + resp2.getErrorMsg() + "]，顺延到下一分钟处理");
                doHandlerNextMin(nick, numIid, planTime, datetime);
            }
            else
            {
                log.error("定时上下架[" + nick + "]调整[" + numIid + "]上架失败[" + resp2.getErrorMsg() + "]");
    
                Updater updater = new Updater();
                updater.addMaybe("nick", nick);
                updater.addMaybe("numIid", numIid);
                updater.addMaybe("planTime", planTime);
                updater.addField("planHandleStatus", 2);
                updater.addField("planHandleTime", datetime);
                updater.addField("planHandleDesc", resp2.getErrorMsg());
                
                ORM.table().update(AssRepostScheduleTime.class, updater);
            }
            
            return;
        }
        
        nums[0]++;
        log.info("定时上下架[" + nick + "]调整[" + numIid + "]成功");

        Updater updater = new Updater();
        updater.addMaybe("nick", nick);
        updater.addMaybe("numIid", numIid);
        updater.addMaybe("planTime", planTime);
        updater.addField("planHandleStatus", 1);
        updater.addField("planHandleTime", datetime);
        updater.addField("planHandleDesc", null);
        
        ORM.table().update(AssRepostScheduleTime.class, updater);
    }

    /** 上架 */
    private void doUpRepost(int[] nums, String nick, long numIid, String planTime, String sessionId, int num, String datetime, boolean isUpdate) throws Exception
    {
        AlibabaItemOperateUpshelfResponse resp = TaobaoService.getItemService().itemUpshelf(nick, sessionId, numIid, num);
        if (resp.isTaobaoFail())
            resp = TaobaoService.getItemService().itemUpshelf(nick, sessionId, numIid, num);

        String type = isUpdate ? "调整" : "上架";
        if (resp.isSuccess())
        {
            nums[0]++;
            log.info("定时上下架[" + nick + "]" + type + "[" + numIid + "]成功");

            Updater updater = new Updater();
            updater.addMaybe("nick", nick);
            updater.addMaybe("numIid", numIid);
            updater.addMaybe("planTime", planTime);
            updater.addField("planHandleStatus", 1);
            updater.addField("planHandleTime", datetime);
            updater.addField("planHandleDesc", null);
            
            ORM.table().update(AssRepostScheduleTime.class, updater);
        }
        else
        {
            nums[1]++;
            if (resp.isTaobaoFail())
            {
                log.error("定时上下架[" + nick + "]" + type + "[" + numIid + "]失败[" + resp.getErrorMsg() + "]，顺延到下一分钟处理");
                doHandlerNextMin(nick, numIid, planTime, datetime);
            }
            else
            {
                log.error("定时上下架[" + nick + "]" + type + "[" + numIid + "]失败[" + resp.getErrorMsg() + "]");
    
                Updater updater = new Updater();
                updater.addMaybe("nick", nick);
                updater.addMaybe("numIid", numIid);
                updater.addMaybe("planTime", planTime);
                updater.addField("planHandleStatus", 2);
                updater.addField("planHandleTime", datetime);
                updater.addField("planHandleDesc", resp.getErrorMsg());
                
                ORM.table().update(AssRepostScheduleTime.class, updater);
            }
        }
    }

    /** 下架 */
    private void doDownRepost(int[] nums, String nick, long numIid, String planTime, String sessionId, String datetime) throws Exception
    {
        AlibabaItemOperateDownshelfResponse resp = TaobaoService.getItemService().itemDownshelf(nick, sessionId, numIid);
        if (resp.isTaobaoFail())
            resp = TaobaoService.getItemService().itemDownshelf(nick, sessionId, numIid);

        if (resp.isSuccess())
        {
            nums[0]++;
            log.info("定时上下架[" + nick + "]下架[" + numIid + "]成功");
            
            Updater updater = new Updater();
            updater.addMaybe("nick", nick);
            updater.addMaybe("numIid", numIid);
            updater.addMaybe("planTime", planTime);
            updater.addField("planHandleStatus", 1);
            updater.addField("planHandleTime", datetime);
            updater.addField("planHandleDesc", null);
            
            ORM.table().update(AssRepostScheduleTime.class, updater);
        }
        else
        {
            nums[1]++;
            if(resp.isTaobaoFail())
            {
                log.error("定时上下架[" + nick + "]下架[" + numIid + "]失败[" + resp.getErrorMsg() + "]，顺延到下一分钟处理");
                doHandlerNextMin(nick, numIid, planTime, datetime);
            }
            else
            {
                log.error("定时上下架[" + nick + "]下架[" + numIid + "]失败[" + resp.getErrorMsg() + "]");
    
                Updater updater = new Updater();
                updater.addMaybe("nick", nick);
                updater.addMaybe("numIid", numIid);
                updater.addMaybe("planTime", planTime);
                updater.addField("planHandleStatus", 2);
                updater.addField("planHandleTime", datetime);
                updater.addField("planHandleDesc", resp.getErrorMsg());
                
                ORM.table().update(AssRepostScheduleTime.class, updater);
            }
        }
    }

    /** 删除一个宝贝 */
    private void doDeleteItem(String nick, long numIid) throws Exception
    {
        ORM.table().delete(AssRepostSchedule.class, nick, numIid);
        ORM.table().delete(AssRepostScheduleTime.class, new Selector("nick", nick).addMaybe("numIid", numIid));
        log.info("定时上下架[" + nick + "]下架[" + numIid + "]已在淘宝端删除,本地删除成功");
    }
    
    /**
     * 延迟到下一分钟处理
     * @param nick
     * @param userDb
     * @param numIid
     * @param planTime
     * @throws Exception
     */
    private void doHandlerNextMin(String nick, long numIid, String planTime, String datetime) throws Exception
    {
        Updater updater = new Updater();
        updater.addMaybe("nick", nick);
        updater.addMaybe("numIid", numIid);
        updater.addMaybe("planTime", planTime);
        updater.addField("planHandleStatus", 3);
        updater.addField("planHandleTime", datetime);
        updater.addField("planHandleDesc", "宝贝调整失败，顺延到下一分钟处理");
        
        ORM.table().update(AssRepostScheduleTime.class, updater);
    }
}
